import { CreateManyDto, CrudRequest, CrudService, GetManyDefaultResponse } from '@dataui/crud';
import { Type } from '@nestjs/common';
import { CrudBaseController } from '../../decorators';
import { CreatControllerOptions } from '../../interfaces/creat-controller-options.interface';
import { ControllerMethods, CurdController } from '../../interfaces/crud-controller.interface';
import { CurdControllerCtor } from './type-utils';
import { ApiResponse } from '@nestjs/swagger';

export function creatController<Entity, ExcludeFn extends ControllerMethods[] = []>(
  EntityClass: Type<Entity>,
  options?: CreatControllerOptions<Entity, ExcludeFn>
): CurdControllerCtor<Entity, ExcludeFn> {
  @CrudBaseController()
  class Controller implements CurdController<Entity> {
    constructor(public service: CrudService<Entity, any>) {}
    createManyBase(req: CrudRequest, dto: CreateManyDto<Entity>): Promise<Entity[]> {
      return this.service.createMany(req, dto);
    }
    createOneBase(req: CrudRequest, dto: Entity): Promise<Entity> {
      return this.service.createOne(req, dto);
    }
    deleteOneBase(req: CrudRequest): Promise<void | Entity> {
      return this.service.deleteOne(req);
    }
    recoverOneBase(req: CrudRequest): Promise<void | Entity> {
      return this.service.recoverOne(req);
    }
    replaceOneBase(req: CrudRequest, dto: Entity): Promise<Entity> {
      return this.service.replaceOne(req, dto);
    }
    updateOneBase(req: CrudRequest, dto: Partial<Entity>): Promise<Entity> {
      return this.service.updateOne(req, dto);
    }
    // @ApiResponse({ type: Object })
    getManyBase(req: CrudRequest): Promise<Entity[] | GetManyDefaultResponse<Entity>> {
      return this.service.getMany(req);
    }
    getOneBase(req: CrudRequest): Promise<Entity> {
      return this.service.getOne(req);
    }
  }
  options.omitMethods?.forEach((item) => delete Controller.prototype[item]);
  return Controller as unknown as CurdControllerCtor<Entity, ExcludeFn>;
}
